/*                          UX-Framework                               
 *                                                                 
 *  iZE Co.,Ltd. Copyright 2009 All rights reserved.          
 *  This file is distributed under the terms of the GNU Lesser 
 *  General Public License, described in file LICENSE.                                     
 */

package jp.ize.ux.acts;

// {{{ imports
import jp.ize.ux.UXObject;
import jp.ize.ux.utils.Util;
import jp.ize.ux.geom.UXPoint;
import jp.ize.ux.acts.Act;
import jp.ize.ux.tween.UXTween;
import jp.ize.ux.tween.easings.Expo;
import jp.ize.ux.tween.easings.Linear;
import flash.filters.BlurFilter;
// }}}
// {{{ enum VisibilityActDir {
enum VisibilityActDir {
	SHOW;
	HIDE;
}
// }}}
// {{{ typedef Visible
typedef Visible = {
	> BasicStateType,
}
// }}}
// {{{ typedef FadeParameter > ActParameter
typedef FadeParameter =
{
	> ActParameter,
	// {{{ var dir : VisibilityActDir
	/**
	 * 表示するのか、隠すのかを指定します。
	 */
	var dir : VisibilityActDir;
	// }}}
}
// }}}
// {{{ typedef FadeBlurParameter > FadeParameter
typedef FadeBlurParameter =
{
	> FadeParameter,
	// {{{ var blurX : Float
	/**
	 * X軸方向のぼかし度合いを指定します。
	 */
	var blurX : Float;
	// }}}
	// {{{ var blurY : Float
	/**
	 * Y軸方向のぼかし度合いを指定します。
	 */
	var blurY : Float;
	// }}}
}
// }}}
// {{{ class VisibilityAct extends Act
/**
 * VisibilityActクラス<br>
 * コンポーネントの表示、非表示に関するアクションを示します。<br>
 *
 * @author		iZE Co., Ltd.<br>
 * @version		$Id$<br>
 */
class VisibilityAct extends Act
{
	// {{{ public function new()
	/**
	* コンストラクタ
	*/
	public function new()
	{
		super();
	}
	// }}}
	// {{{ public function fade( fp:FadeParameter, ?interp:Visible->FadeParameter ) : Visible -> Void
	/**
	 * フェードイン・アウトの動きです。
	 */
	public function fade( fp:FadeParameter, ?interp:Visible->FadeParameter ) : Visible -> Void
	{
		var me = this;
		return function( state : Visible ) : Void {
			var param = fp;
			if ( interp!=null ) param = interp(state);
			var goal:Float = 0.0;
			var flag:Bool = true;
			switch ( param.dir ) {
				case SHOW:
					goal = 1.0;
					flag = true;
				case HIDE:
					goal = 0.0;
					flag = false;
			}
			var getter = function(obj:Visible): {v:Float} {
				return {v:obj.target.alpha};
			};
			var setter = function(obj:Visible, init:{v:Float}, end:{v:Float}, v:Float) {
				obj.target.alpha = init.v+(end.v-init.v)*v;
			};
			var end = {v:goal};
			var tw = new UXTween<Visible,{v:Float}>(state, end, getter, setter, param.time,
						param.transition);
			tw.setEndTweenHandler( function(e:Dynamic){
				state.target.visible = flag;
				if ( state.subject!=null ) {
					state.subject.notify(Act.STOP);
				}
			});
			var id = "vis";
			if ( !me.tm.objects.exists(id) ) {
				me.tm.registObject(id,state);
			}
			me.tm.addTweenChain(id,tw);
			me.tm.start(id,false,state.target);
		};
	}
	// }}}
	// {{{ public function fade_and_blur( fbp:FadeBlurParameter, ?interp:Visible->FadeBlurParameter ) : Visible -> Void
	/**
	 * フェードイン・アウトの動きです。
	 */
	public function fade_and_blur( fbp:FadeBlurParameter, ?interp:Visible->FadeBlurParameter ) : Visible -> Void
	{
		var me = this;
		return function( state : Visible ) : Void {
			var param = fbp;
			if ( interp!=null ) param = interp(state);
			var goal:Float = 0.0;
			var flag:Bool = true;
			switch ( param.dir ) {
				case SHOW:
					goal = 1.0;
					flag = true;
				case HIDE:
					goal = 0.0;
					flag = false;
			}
			var getter = function(obj:Visible): {v:Float} {
				return {v:obj.target.alpha};
			};
			var setter = function(obj:Visible, init:{v:Float}, end:{v:Float}, v:Float) {
				obj.target.alpha = init.v+(end.v-init.v)*v;
				if ( flag ) {
					obj.target.filters = [ new BlurFilter(param.blurX*(1-v),param.blurY*(1-v)) ];
				} else {
					obj.target.filters = [ new BlurFilter(param.blurX*v,param.blurY*v) ];
				}
			};
			var end = {v:goal};
			var tw = new UXTween<Visible,{v:Float}>(state, end, getter, setter, param.time,
						param.transition);
			tw.setEndTweenHandler( function(e:Dynamic){
				state.target.visible = flag;
				state.target.filters = [];
				if ( state.subject!=null ) {
					state.subject.notify(Act.STOP);
				}
			});
			var id = "vis";
			if ( !me.tm.objects.exists(id) ) {
				me.tm.registObject(id,state);
			}
			me.tm.addTweenChain(id,tw); 
			me.tm.start(id,false,state.target);
		};
	}
	// }}}
}
// }}}
